<!doctype html>
<!--
@license
Copyright (c) 2017 The Polymer Project Authors. All rights reserved.
This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
Code distributed by Google as part of the polymer project is also
subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
-->
<html>
<head>
  <meta charset="utf-8">
  <script src="../../node_modules/@webcomponents/webcomponentsjs/webcomponents-bundle.js"></script>
  <script>
    window.ShadyCSS['cssBuild'] = true;
  </script>
  <script src="wct-browser-config.js"></script>
  <script src="../../node_modules/wct-browser-legacy/browser.js"></script>
  <script type="module">
    import {
      setUseAdoptedStyleSheetsWithBuiltCSS,
      supportsAdoptingStyleSheets,
    } from '../../lib/utils/settings.js';
    setUseAdoptedStyleSheetsWithBuiltCSS(true);
    window.supportsAdoptingStyleSheets = supportsAdoptingStyleSheets;
    let define = window.customElements.define;
    let order = [];
    window.customElements.define = function(name, fn, options) {
      order.push(name);
      return define.call(window.customElements, name, fn, options);
    };
    customElements.defineOrder = order;
  </script>
</head>
<body>

<dom-module id="x-keyframes">
  <template css-build="shadow">
    <style>
      :host {
        display: block;
        position: relative;
        border: 10px solid blue;
        left: 0px;
        /* Prefix required by Safari <= 8 */
        -webkit-animation-duration: 0.3s;
        animation-duration: 0.3s;
        -webkit-animation-fill-mode: forwards;
        animation-fill-mode: forwards;
      }

      :host([animated]) {
        /* Prefix required by Safari <= 8 */
        -webkit-animation-name: x-keyframes-animation;
        animation-name: x-keyframes-animation;
      }

      /* Prefix required by Safari <= 8 */
      @-webkit-keyframes x-keyframes-animation {
        0% {
          left: var(--keyframes0, 0px);
        }

        100% {
          left: var(--keyframes100, 10px);
        }
      }
      @keyframes x-keyframes-animation {
        0% {
          left: var(--keyframes0, 0px);
        }

        100% {
          left: var(--keyframes100, 10px);
        }
      }
    </style>
    x-keyframes
  </template>
  <script type="module">
import { Polymer } from '../../polymer-legacy.js';
Polymer({
  is: 'x-keyframes',
  properties: {
    animated: {
      type: Boolean,
      value: false,
      reflectToAttribute: true
    }
  }
});
</script>
</dom-module>
<dom-module id="x-gchild">
  <template css-build="shadow">
    <style>
    </style>
    <div id="target">x-gchild</div>
  </template>
</dom-module>
<script type="module">
import { Polymer } from '../../polymer-legacy.js';
Polymer({
  is: 'x-gchild'
});
</script>

<dom-module id="x-child">
  <template css-build="shadow">
    <div id="simple">simple</div>
    <div id="complex1" class="scoped">complex1</div>
    <div id="complex2" selected>complex2</div>
    <div id="media">media</div>
    <div id="shadow" class="shadowTarget">shadowTarget</div>
    <div id="deep" class="deepTarget">deepTarget</div>
    <x-gchild id="gchild1"></x-gchild>
    <x-gchild id="gchild2" class="wide"></x-gchild>
  </template>
</dom-module>
<script type="module">
import { Polymer } from '../../polymer-legacy.js';
Polymer({
  is: 'x-child',
  hostAttributes: {
    class: 'nug'
  }
});
</script>

<dom-module id="x-child2">
  <template css-build="shadow">
    <style>
      :host(.wide) #target{
        border: none;
      }
    </style>
    <div id="target">x-child2</div>
  </template>
</dom-module>
<script type="module">
import { Polymer } from '../../polymer-legacy.js';
Polymer({
  is: 'x-child2'
});
</script>

<dom-module id="x-scope-class">
  <template css-build="shadow">
    <div id="scope">Trivial</div>
  </template>
  <script type="module">
import { Polymer } from '../../polymer-legacy.js';
Polymer({
  is: 'x-scope-class'
});
</script>
</dom-module>

<dom-module id="x-class-literal">
  <template css-build="shadow">
    <div id="scope" class$="a [[b]] c" class="d e">Trivial</div>
  </template>
  <script type="module">
import { Polymer } from '../../polymer-legacy.js';
Polymer({
  is: 'x-class-literal'
});
</script>
</dom-module>



<dom-module id="x-styled">
  <template css-build="shadow">
    <style>
      :host {
        display: block;
        border: 1px solid orange;
        --keyframes100: 100px;
      }

      :host(.wide) {
        border-width: 2px;
      }

      :host(.wide)::after {
        content: '-content-';
      }

      #keyframes2.special {
        --keyframes100: 200px;
      }

      #simple {
        border: 3px solid orange;
      }

      .scoped, [selected] {
        border: 4px solid pink;
      }

      @media(max-width: 10000px) {
        .media {
          border: 5px solid brown;
        }
      }

      .container ::slotted(*) {
        border: 6px solid navy;
      }

      #priority {
        border: 9px solid orange;
      }

      .container1 > ::slotted([slot=content1]) {
        border: 13px solid navy;
      }

      .container2 > ::slotted([slot=content2]) {
        border: 14px solid navy;
      }

      .computed {
        border: 15px solid orange;
      }

      .computeda {
        border: 20px solid orange;
      }

      .a.computedb {
        border: 16px solid gray;
      }

      #child {
        border: 16px solid tomato;
        display: block;
      }

      svg {
        margin-top: 20px;
      }

      #circle {
        fill: seagreen;
        stroke-width: 1px;
        stroke: tomato;
      }
    </style>
    <slot name="blank"></slot>
    <div id="simple">simple</div>
    <div id="complex1" class="scoped">complex1</div>
    <div id="complex2" selected>complex2</div>
    <div id="media" class="media">media</div>
    <div class="container1">
      <slot name="content1"></slot>
    </div>
    <div class="container2">
      <slot name="content2"></slot>
    </div>
    <div class="container">
      <slot></slot>
    </div>
    <x-child id="child"></x-child>
    <div id="priority">priority</div>
    <x-child2 class="wide" id="child2"></x-child2>
    <div id="computed" class$="{{computeClass(aClass)}}">Computed</div>
    <div>
      <div id="computed2" class$="a {{computeClass('computedb')}}">Computed</div>
    </div>
    <div id="repeatContainer">
      <template css-build="shadow" id="repeat" is="dom-repeat" items="{{items}}">
        <a class$="{{aaClass}}">A Computed</a>
      </template>
    </div>
    <svg height="25" width="25">
      <circle id="circle" cx="12" cy="12" r="10"></circle>
    </svg>
    <x-scope-class id="scopeClass"></x-scope-class>
    <x-keyframes id="keyframes"></x-keyframes>
    <x-keyframes id="keyframes2"></x-keyframes>
  </template>
</dom-module>
<script type="module">
import { Polymer } from '../../polymer-legacy.js';
Polymer({
  is: 'x-styled',

  properties: {
    items: {value: [{}]}
  },

  computeClass: function(className) {
    return className;
  }

});
</script>

<template css-build="shadow" id="dynamic">
  <div class="added">
    Added
    <div class="sub-added">
      Sub-added
    </div>
  </div>
</template>

<dom-module id="x-dynamic-scope">
  <template css-build="shadow">
    <style>
      .added {
        border: 17px solid beige;
      }

      .sub-added {
        border: 18px solid #fafafa;
      }
    </style>
    <div id="container"></div>
  </template>
</dom-module>
<script type="module">
import { Polymer } from '../../polymer-legacy.js';
var doc = window.document;
var dynamic = doc.querySelector('template#dynamic');

Polymer({
  is: 'x-dynamic-scope',
  ready: function() {
    // simulate 3rd party action by using normal dom to add to element.
    var dom = document.importNode(dynamic.content, true);
    this.$.container.appendChild(dom);
  }
});
</script>

<template css-build="shadow" id="dynamic-style-template">
  <style>
    :host {
      border: 40px solid tomato;
    }
  </style>
  <div>big border</div>
</template>

<script type="module">
import { Polymer } from '../../polymer-legacy.js';
var doc = window.document;
var template = doc.querySelector('template#dynamic-style-template');

Polymer({
  is: 'x-dynamic-template',
  registered: function() {
    this._template = template;
  }
});
</script>

<template css-build="shadow" id="svg">
  <svg class="svg" viewBox="0 0 24 24">
    <circle id="circle" r="12" cx="12" cy="12" />
  </svg>
</template>

<dom-module id="x-dynamic-svg">
  <template css-build="shadow">
    <style>
      .svg {
        height: 24px;
        width: 24px;
      }
      #circle {
        fill: red;
        fill-opacity: 0.5;
      }
    </style>
    <div id="container"></div>
  </template>
  <script type="module">
import { Polymer } from '../../polymer-legacy.js';
var doc = window.document;
var template = doc.querySelector('template#svg');

Polymer({
  is: 'x-dynamic-svg',
  ready: function() {
    this.scopeSubtree(this.$.container, true);
    var dom = document.importNode(template.content, true);
    this.$.container.appendChild(dom);
  }
});
</script>
</dom-module>

<dom-module id="x-specificity">
  <template css-build="shadow">
    <style>
      :host {
        border-top: 1px solid red;
      }
      :host(.bar) {
        border-top: 2px solid red;
      }
    </style>
    <slot></slot>
  </template>
  <script type="module">
import { Polymer } from '../../polymer-legacy.js';
Polymer({is: 'x-specificity'});
</script>
</dom-module>

<custom-style>
  <style>
    html {
      --x-specificity-parent: 10px solid blue;
      --x-specificity-nested: 3px solid red;
    }
  </style>
</custom-style>

<dom-module id="x-specificity-parent">
  <template css-build="shadow">
    <style>
      ::slotted(:not(template)) {
        border: var(--x-specificity-parent);
      }
    </style>
    <slot></slot>
  </template>
  <script type="module">
import { Polymer } from '../../polymer-legacy.js';
Polymer({is: 'x-specificity-parent'});
</script>
</dom-module>

<dom-module id="x-specificity-nested">
  <template css-build="shadow">
    <style>
      :host {
        border: var(--x-specificity-nested);
      }
    </style>
  </template>
  <script type="module">
import { Polymer } from '../../polymer-legacy.js';
Polymer({is: 'x-specificity-nested'});
</script>
</dom-module>

<custom-style>
  <style>
    html {
      --x-overriding: 1px solid red;
    }
  </style>
</custom-style>

<dom-module id="x-overriding">
  <template css-build="shadow">
    <style>
      .red {
        border-top: var(--x-overriding);
      }
      .green {
        border-top: var(--x-overriding);
        border-top: 2px solid green;
      }
      .red-2 {
        border-top: 2px solid green;
        border-top: var(--x-overriding);
      }
      .blue {
        border-top: var(--x-overriding);
        border-top: 3px solid blue;
      }
    </style>

    <div class="red">red</div>
    <div class="green">green</div>
    <div class="red-2">green-2</div>
    <div class="blue">blue</div>
  </template>
</dom-module>

<script type="module">
import { Polymer } from '../../polymer-legacy.js';
Polymer({
  is: 'x-overriding'
});
</script>

<dom-module id="x-attr-selector">
  <template css-build="shadow">
    <style>
      #foo1 ~ #bar1 {
        border: 2px solid red;
      }

      #foo1 ~ #bar1 ~ #foo2[attr~=foo2] ~ #bar2[attr~=bar2]  {
        border: 4px solid red;
      }

      #foo1 ~ #bar1 ~ #foo2[attr~=foo2] ~ #bar2[attr~=bar2] ~ #foo3[attr~=foo3][a~=a] ~ #bar3[attr~=bar3][a~=a] {
        border: 6px solid red;
      }
    </style>
    <div id="foo1"></div>
    <div id="bar1">bar1</div>
    <div id="foo2" attr="foo2"></div>
    <div id="bar2" attr="bar2">bar2</div>
    <div id="foo3" attr="foo3" a="a"></div>
    <div id="bar3" attr="bar3" a="a">bar3</div>

  </template>
  <script type="module">
import { Polymer } from '../../polymer-legacy.js';
Polymer({is: 'x-attr-selector'});
</script>
</dom-module>

<dom-module id="x-shared1">
  <template css-build="shadow">
    <style>
      :host(x-shared1) {
        display: block;
        border: 2px solid orange;
      }

      :host(x-shared2) {
        display: block;
        border: 4px solid orange;
      }

      :host(.x-shared1) {
        top: 10px;
      };
    </style>
    x-shared1
  </template>
  <script type="module">
import { Polymer } from '../../polymer-legacy.js';
Polymer({is: 'x-shared1'});
</script>
</dom-module>

<dom-module id="x-shared2">
  <template css-build="shadow">
    <style>
      :host(x-shared1) {
        display: block;
        border: 2px solid orange;
      }

      :host(x-shared2) {
        display: block;
        border: 4px solid orange;
      }

      :host(.x-shared1) {
        top: 10px;
      };
    </style>
    x-shared2
  </template>
  <script type="module">
import { Polymer } from '../../polymer-legacy.js';
Polymer({is: 'x-shared2'});
</script>
</dom-module>

<dom-module id="x-slotted">
  <template css-build="shadow">
    <style>
    ::slotted(.auto-content) {
      border: 2px solid orange;
    }
    .bar, ::slotted(.complex-child) {
      border: 6px solid navy;
    }
    #container ::slotted(*) {
      border: 8px solid green;
    }
    </style>
    <slot></slot>
    <div id="container">
      <slot name="container"></slot>
    </div>
  </template>
  <script type="module">
import { Polymer } from '../../polymer-legacy.js';
Polymer({is: 'x-slotted'});
</script>
</dom-module>

<template css-build="shadow" id="xClass">
  <style>
    :host {
      display: block;
      border: 1px solid orange;
    }
  </style>
</template>
<script type="module">
import { PolymerElement, html } from '../../polymer-element.js';
customElements.define('x-class-no-is', class extends PolymerElement {
  static get template() {
    return window.xClass;
  }
});

customElements.define('x-template-string', class extends PolymerElement {
  static get template() {
    return html`<style>
      :host {
        display: block;
        border: 1px solid orange;
      }
    </style>;`;
  }
});
</script>


  <div class="scoped">no margin</div>

  <x-styled>
    <div slot="content1">Foo</div>
    <div slot="content2">Bar</div>
    <div class="content">Content</div>
  </x-styled>

  <x-styled class="wide"></x-styled>

  <x-dynamic-scope></x-dynamic-scope>

  <dom-bind id="bind">
    <template css-build="shadow">
      <div id="dom-bind-static" class="static">static</div>
      <span id="dom-bind-dynamic" class$="[[dynamic]]">[[dynamic]]</span>
    </template>
  </dom-bind>

  <x-dynamic-svg></x-dynamic-svg>
  <x-specificity></x-specificity>
  <x-specificity class="bar"></x-specificity>
  <x-specificity-parent>
    <x-specificity-nested></x-specificity-nested>
  </x-specificity-parent>
  <x-overriding></x-overriding>

  <dom-module id="x-nested-style">
    <template css-build="shadow">
      <div id="container">
        <style>
          :host {
            display: block;
            border: 10px solid black;
          }
        </style>
        <style>
            :host {
              padding-top: 10px;
            }
          </style>
      </div>
    </template>
    <script type="module">
import { PolymerElement } from '../../polymer-element.js';
class XNestedStyle extends PolymerElement {
  static get is() {return 'x-nested-style';}
}
customElements.define(XNestedStyle.is, XNestedStyle);
</script>
  </dom-module>

  <dom-module id="x-interleaved-styles">
    <template css-build="shadow">
      <style include="x-nested-style"></style>
      <style>
        :host {
          padding-top: 5px;
        }
      </style>
      <style>
        :host {
          color: blue;
        }
      </style>
    </template>
    <script type="module">
import { PolymerElement } from '../../polymer-element.js';
class XInterleaved extends PolymerElement {
  static get is() {return 'x-interleaved-styles';}
}
customElements.define(XInterleaved.is, XInterleaved);
</script>
  </dom-module>

<script type="module">
  import { PolymerElement, html } from '../../polymer-element.js';
  class ClassBindingUndefined extends PolymerElement {
    static get is() { return 'class-binding-undefined'; }
    static get properties() {
      return {
        data: {
          type: Object
        }
      };
    }
    static get template() {
      return html`
      <style>
        div {
          border: 10px solid black;
        }
      </style>
      <div id="div" class$="[[data.class]]">Foo</div>
      `;
    }
  }
  customElements.define(ClassBindingUndefined.is, ClassBindingUndefined);
</script>

<script type="module">
import { dom } from '../../lib/legacy/polymer.dom.js';
import { flush } from '../../lib/utils/flush.js';
function assertComputed(element, value, property, pseudo) {
  var computed = getComputedStyle(element, pseudo);
  property = property || 'border-top-width';
  if (Array.isArray(value)) {
    assert.oneOf(computed[property], value, 'computed style incorrect for ' + property);
  } else {
    assert.equal(computed[property], value, 'computed style incorrect for ' + property);
  }
}

var styled = document.querySelector('x-styled');
var styledWide = document.querySelector('x-styled.wide');
var unscoped = document.querySelector('.scoped');

suite('scoped-styling', function() {

  test('uses adoptedStyleSheets if possible', function() {
    if (!window.supportsAdoptingStyleSheets) {
      this.skip();
    }
    assert.ok(styled.shadowRoot.adoptedStyleSheets.length);
  });

  test(':host, :host(...)', function() {
    assertComputed(styled, '1px');
    assertComputed(styledWide, '2px');
    assertComputed(styled, ['', 'none'], 'content', '::after');
    assertComputed(styledWide, ['"-content-"', '-content-'], 'content', '::after');
  });

  test('scoped selectors, simple and complex', function() {
    assertComputed(styled.$.simple, '3px');
    assertComputed(styled.$.complex1, '4px');
    assertComputed(styled.$.complex2, '4px');
  });

  test('media query scoped selectors', function() {
    assertComputed(styled.$.media, '5px');
  });

  test('upper bound encapsulation', function() {
    assertComputed(unscoped, '0px');
  });

  test('lower bound encapsulation', function() {
    assertComputed(styled.$.child.$.simple, '0px');
    assertComputed(styled.$.child.$.complex1, '0px');
    assertComputed(styled.$.child.$.complex2, '0px');
    assertComputed(styled.$.child.$.media, '0px');
  });

  test('::slotted selectors', function() {
    var content = document.querySelector('.content');
    var content1 = document.querySelector('[slot=content1]');
    var content2 = document.querySelector('[slot=content2]');
    assertComputed(content, '6px');
    assertComputed(content1, '13px');
    assertComputed(content2, '14px');
  });

  test('auto ::slotted selector', function() {
    var x = document.createElement('x-slotted');
    var d1 = document.createElement('div');
    d1.classList.add('auto-content');
    d1.textContent = 'auto-content';
    document.body.appendChild(x);
    dom(x).appendChild(d1);
    flush();
    assertComputed(d1, '2px');
  });

  test('::slotted + child in complex selector', function() {
    var x = document.createElement('x-slotted');
    var d1 = document.createElement('div');
    d1.classList.add('complex-child');
    d1.textContent = 'complex-child';
    document.body.appendChild(x);
    dom(x).appendChild(d1);
    flush();
    assertComputed(d1, '6px');
  });

  test('::slotted + named slot', function() {
    var x = document.createElement('x-slotted');
    var d1 = document.createElement('div');
    d1.setAttribute('slot', 'container');
    d1.textContent = 'named slot child';
    document.body.appendChild(x);
    dom(x).appendChild(d1);
    flush();
    assertComputed(d1, '8px');
  });

  test('elements dynamically added/removed from root', function() {
    var d = document.createElement('div');
    d.classList.add('scoped');
    d.textContent = 'Dynamically... Scoped!';
    dom(styled.root).appendChild(d);
    flush();
    assertComputed(d, '4px');
    dom(document.body).appendChild(d);
    flush();
    assert.notInclude(d.getAttribute('style-scoped') || '', styled.is, 'scoping attribute not removed when added to other root');
    assert.notInclude(d.className, styled.is, 'scoping class not removed when added to other root');
    assertComputed(d, '0px');
    dom(styled.root).appendChild(d);
    flush();
    assertComputed(d, '4px');
  });

  test('elements dynamically added/removed from host', function() {
    var d = document.createElement('div');
    d.classList.add('scoped');
    d.slot = 'blank';
    d.textContent = 'Dynamically... unScoped!';
    dom(styled).appendChild(d);
    flush();
    assertComputed(d, '0px');
    dom(document.body).appendChild(d);
    flush();
    assert.notInclude(d.getAttribute('style-scoped') || '', styled.is, 'scoping attribute not removed when added to other root');
    assert.notInclude(d.className, styled.is, 'scoping class not removed when added to other root');
    dom(styled).appendChild(d);
    flush();
    assertComputed(d, '0px');
    dom(styled).removeChild(d);
    flush();
    assert.notInclude(d.getAttribute('style-scoped') || '', styled.is, 'scoping attribute not removed when removed from root');
    assert.notInclude(d.className, styled.is, 'scoping class not removed when removed from root');
    dom(styled).appendChild(d);
    flush();
    assertComputed(d, '0px');
  });

  test('keyframes change scope', function(done) {
    if (navigator.userAgent.match('Edge') && (!window.ShadyCSS || window.ShadyCSS.nativeCss)) {
      // skip test due to missing variable support in keyframes
      // https://developer.microsoft.com/en-us/microsoft-edge/platform/issues/12084341/
      this.skip();
    }
    var xKeyframes = styled.$.keyframes;

    var onAnimationEnd = function() {
      xKeyframes.removeEventListener('animationend', onAnimationEnd);
      xKeyframes.removeEventListener('webkitAnimationEnd', onAnimationEnd);
      assertComputed(xKeyframes, '100px', 'left');

      xKeyframes = styled.$.keyframes2;

      onAnimationEnd = function() {
        xKeyframes.removeEventListener('animationend', onAnimationEnd);
        xKeyframes.removeEventListener('webkitAnimationEnd', onAnimationEnd);
        assertComputed(xKeyframes, '200px', 'left');
        done();
      };

      xKeyframes.addEventListener('animationend', onAnimationEnd);
      xKeyframes.addEventListener('webkitAnimationEnd', onAnimationEnd);

      dom(xKeyframes).classList.add('special');
      xKeyframes.updateStyles();
      xKeyframes.animated = true;
    };

    xKeyframes.addEventListener('animationend', onAnimationEnd);
    xKeyframes.addEventListener('webkitAnimationEnd', onAnimationEnd);

    xKeyframes.animated = true;
    assertComputed(xKeyframes, '0px', 'left');
  });

  test('elements with computed classes', function() {
    assertComputed(styled.$.computed, '0px');
    styled.aClass = 'computed';
    assertComputed(styled.$.computed, '15px');
    assertComputed(styled.$.computed2, '16px');
  });

  test('<a> with computed classes dynamically added', function() {
    assertComputed(styled.$.repeatContainer.firstElementChild, '0px');
    styled.aaClass = 'computeda';
    assertComputed(styled.$.repeatContainer.firstElementChild, '20px');
  });

  test('elements with hostAttributes: class', function() {
    assertComputed(styled.$.child, '16px');
  });

  test('element subtree added via dom api', function() {
    var container = document.querySelector('x-dynamic-scope').$.container;
    var a = container.querySelector('.added');
    assertComputed(a, '17px');
    var b = container.querySelector('.sub-added');
    assertComputed(b, '18px');
  });

  test('styles in dynamically selected template', function() {
    var el = document.createElement('x-dynamic-template');
    document.body.appendChild(el);
    if (el.shadowRoot) {
      // style properly removed
      assert.notOk(el.querySelector('style'));
    }
    assertComputed(el, '40px');
    document.body.removeChild(el);
  });

  test('attribute inclusive selector and general sibling selectors', function() {
    var e = document.createElement('x-attr-selector');
    document.body.appendChild(e);
    flush();
    assertComputed(e.$.bar1, '2px');
    assertComputed(e.$.bar2, '4px');
    assertComputed(e.$.bar3, '6px');
  });

  test('svg classes are dynamically scoped correctly', function() {
    var container = document.querySelector('x-dynamic-svg').$.container;
    var svg = container.querySelector('.svg');
    var computed = getComputedStyle(svg);
    assert.equal(computed.height, '24px');
    assert.equal(computed.width, '24px');
    var circle = container.querySelector('#circle');
    computed = getComputedStyle(circle);
    assert.equal(computed['fill-opacity'], '0.5');
  });

  test(':host with element tag selector', function() {
    var s1 = document.createElement('x-shared1');
    document.body.appendChild(s1);
    assertComputed(s1, '2px');
    var s2 = document.createElement('x-shared2');
    document.body.appendChild(s2);
    assertComputed(s2, '4px');
  });

  test(':host with superset of element tag selector does not leak', function() {
    var t = document.createElement('div');
    t.textContent = 'host leak test';
    t.classList.add('x-shared1');
    document.body.appendChild(t);
    assertComputed(t, 'auto', 'top');
  });

  test(':host(...) with non-matching type selector does not leak', function() {
    var t = document.createElement('x-shared1x-shared2');
    t.textContent = ':host(non-matching-type-selector)';
    document.body.appendChild(t);
    assertComputed(t, '0px');
    t = document.createElement('x-shared2x-shared1');
    t.textContent = ':host(non-matching-type-selector)';
    document.body.appendChild(t);
    assertComputed(t, '0px');
  });

  test('static is not required for scoping styling', function() {
    var e = document.createElement('x-class-no-is');
    document.body.appendChild(e);
    assertComputed(e, '1px');
  });

  test('template string has scoped styling', function() {
    var e = document.createElement('x-template-string');
    document.body.appendChild(e);
    assertComputed(e, '1px');
  });

  test('styles work correctly when not direct children of the template', function() {
    var e = document.createElement('x-nested-style');
    document.body.appendChild(e);
    assertComputed(e, '10px');
    assertComputed(e, '10px', 'padding-top');
  });

  test('interleaved styles and styles with includes work as expected', function() {
    var e = document.createElement('x-interleaved-styles');
    document.body.appendChild(e);
    assertComputed(e, '5px', 'padding-top');
  });

  test('initial literal values in class are preserved when a class$ binding is present', function() {
    var e = document.createElement('x-class-literal');
    document.body.appendChild(e);
    var el = e.$.scope;
    assert.isTrue(el.classList.contains('a'));
    assert.isTrue(el.classList.contains('c'));
    assert.isTrue(el.classList.contains('d'));
    assert.isTrue(el.classList.contains('e'));
  });

  test('scoping classes are preserved when a class$ binding resolves to undefined', function() {
    const e = document.createElement('class-binding-undefined');
    document.body.appendChild(e);
    const el = e.$.div;
    assertComputed(el, '10px');
  });

});
</script>
</body>
</html>
